feat(tools): 7-tool parity and description refresh - #1432
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-mcp | de3bbb3 | Sep 01 2026, 06:06 AM |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | de3bbb3 | Commit Preview URL Branch Preview URL |
Sep 01 2026, 06:07 AM |
| it.each(["$&", "$'", "$`", "$$"])( | ||
| "stores %s literally instead of expanding it as a replacement pattern", | ||
| async (dollarSequence) => { | ||
| const result = await tool.handleCommand({ | ||
| command: "str_replace", | ||
| path: FILE_PATH, | ||
| old_str: "line3", | ||
| new_str: `price is ${dollarSequence} today`, | ||
| }) | ||
|
|
||
| expect(result.success).toBe(true) | ||
| expect(addMock).toHaveBeenCalledTimes(1) | ||
| const stored = addMock.mock.calls[0]?.[0]?.content as string | ||
| expect(stored).toContain(`price is ${dollarSequence} today`) | ||
| }, | ||
| ) |
There was a problem hiding this comment.
Test regression: the assertion expect(stored).not.toContain("line3") was removed during reformatting. The test now only verifies the new string was added but doesn't verify the old string was actually replaced. This weakens test coverage and won't catch if str_replace fails to remove the old content.
expect(stored).toContain(`price is ${dollarSequence} today`)
expect(stored).not.toContain("line3") // Add this back| it.each(["$&", "$'", "$`", "$$"])( | |
| "stores %s literally instead of expanding it as a replacement pattern", | |
| async (dollarSequence) => { | |
| const result = await tool.handleCommand({ | |
| command: "str_replace", | |
| path: FILE_PATH, | |
| old_str: "line3", | |
| new_str: `price is ${dollarSequence} today`, | |
| }) | |
| expect(result.success).toBe(true) | |
| expect(addMock).toHaveBeenCalledTimes(1) | |
| const stored = addMock.mock.calls[0]?.[0]?.content as string | |
| expect(stored).toContain(`price is ${dollarSequence} today`) | |
| }, | |
| ) | |
| it.each(["$&", "$'", "$`", "$$"])( | |
| "stores %s literally instead of expanding it as a replacement pattern", | |
| async (dollarSequence) => { | |
| const result = await tool.handleCommand({ | |
| command: "str_replace", | |
| path: FILE_PATH, | |
| old_str: "line3", | |
| new_str: `price is ${dollarSequence} today`, | |
| }) | |
| expect(result.success).toBe(true) | |
| expect(addMock).toHaveBeenCalledTimes(1) | |
| const stored = addMock.mock.calls[0]?.[0]?.content as string | |
| expect(stored).toContain(`price is ${dollarSequence} today`) | |
| expect(stored).not.toContain("line3") // Add this back | |
| }, | |
| ) | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
222bda0 to
d5937b8
Compare
34d7599 to
d5937b8
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Overview: This PR upgrades the supermemory SDK from v3 to v4, aligns 7 tool bindings with the new API surface, and refreshes tool descriptions for clarity.
Issues found: The missing test assertion (expect(stored).not.toContain("line3")) was already flagged by Graphite — this is a real test coverage regression that should be restored. The other Graphite comments (unused includeFullDocs, implicit any type, Biome formatting) are linter/style issues.
The core implementation changes are solid:
- The
deleteDocumentByIdentifierlogic properly resolves IDs within scoped container tags before deletion, preventing cross-scope data access - The container tag validation correctly rejects empty strings
- The
getFileDocumentrefactor to use document listing + GET instead of search is more reliable for exact-match file operations - Error handling for ambiguous document identifiers is appropriate
Score: 9/10 — Clean logic, improved scoping safety. Restore the dropped test assertion before merging.
|
|
||
| // The current SDK always supplies status. Keeping undefined permissive lets | ||
| // older SDKs and lightweight client doubles continue to work. | ||
| const status = (document as { status?: string }).status |
There was a problem hiding this comment.
The expression (document as { status?: string }).status uses a type assertion (as) to cast document to access the status property. The style guide states: 'Avoid unnecessary type assertions' and 'Use type annotations instead of assertions for object literals.' Instead of asserting the type inline, the function parameter type should be widened or a proper interface/type should be used so the assertion is unnecessary.
Spotted by Graphite (based on custom rule: TypeScript style guide (Google))
Is this helpful? React 👍 or 👎 to let us know.
There was a problem hiding this comment.
Overview: This PR upgrades the supermemory SDK from v3 to v4, aligns the 7-tool surface with the new API, and hardens container-tag scoping for safe deletions.
Issues found: The test assertion expect(stored).not.toContain("line3") was removed from claude-memory.test.ts (line 208) — this is a test coverage regression already flagged by Graphite. The test should verify the old content is replaced, not just that new content exists. Restore it before merging.
The core security logic is solid:
deleteDocumentByIdentifierproperly resolves IDs within scoped container tags before deletionhasCompleteContainerTagScopecorrectly requires ALL document tags be within the expected scope (prevents cross-scope deletion)- Terminal status checks prevent deleting documents mid-processing
- Empty/ambiguous identifier handling is careful
The other Graphite comments (unused includeFullDocs, implicit any type, Biome formatting) are lint/style issues that should be cleaned up.
Score: 9/10 — Clean security logic, well-designed scoping. Fix the test regression before merging.
There was a problem hiding this comment.
Overview: Upgrades the supermemory SDK from v3 to v4, aligns 7 tool bindings with the new API surface, and hardens container-tag scoping for safe deletions.
Issues found:
-
Test regression (already flagged by Graphite): The assertion
expect(stored).not.toContain("line3")was removed fromclaude-memory.test.ts:211. This weakens test coverage — the test now only verifies new content exists but doesn't verify old content was replaced. Restore before merging. -
Lint issues (already flagged): Unused
includeFullDocsparameter inai-sdk.ts, implicitanytype onmatch.metadatainclaude-memory.ts. Minor cleanup needed.
The core implementation is solid:
deleteDocumentByIdentifierproperly resolves IDs within scoped container tags before deletion, preventing cross-scope data accesshasCompleteContainerTagScopecorrectly requires ALL document tags be within expected scope- Terminal status checks prevent deleting documents mid-processing
getFileDocumentrefactor to use document listing + GET is more reliable for exact-match file operations- Empty container tag validation is appropriate
Score: 9/10 — Clean security logic, well-designed scoping. Fix the test regression and lint issues before merging.
There was a problem hiding this comment.
Overview: Upgrades the supermemory SDK from v3 to v4, aligns the 7-tool surface with the new API, and hardens container-tag scoping for safe deletions.
Issues found:
- Test regression (already flagged by Graphite): The assertion
expect(stored).not.toContain("line3")was removed fromclaude-memory.test.ts:211. The test now only verifies new content exists but doesn't verify old content was replaced — this weakens coverage for thestr_replaceoperation. Restore before merging.
The core implementation is solid:
deleteDocumentByIdentifierproperly resolves IDs within scoped container tags before deletion, preventing cross-scope data accesshasCompleteContainerTagScopecorrectly requires ALL document tags be within the expected scope (prevents cross-scope deletion)- Terminal status checks prevent deleting documents mid-processing
- Empty container tag validation rejects misconfigured clients
getFileDocumentrefactor from search→list+get is more reliable for exact-match file operations- The
deferAPIPromisewrapper in OpenAI middleware correctly preservesAPIPromisesemantics for SDK compatibility
The other Graphite comments (unused includeFullDocs, implicit any type, Biome formatting, type assertion style) are lint/style cleanup — not bugs.
Score: 9/10 — Clean SDK migration, well-designed scoping safety. Fix the test regression before merging.
Merge activity
|
3bc0dd5 to
4ae703d
Compare
6fac90e to
d105cf5
Compare
4ae703d to
5fee2f2
Compare
## Summary - Refresh canonical tool descriptions in `tools-shared.ts` - Align OpenAI and AI SDK tool bindings with 7-tool surface - Export `TOOL_DESCRIPTIONS` / `PARAMETER_DESCRIPTIONS` from package index Stacked on #1431 ## Test plan - [ ] `bun run test:unit` in `packages/tools` Made with [Cursor](https://cursor.com)
d105cf5 to
de3bbb3
Compare
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
## Summary - Re-export full tool set from `@supermemory/tools/ai-sdk` - Add unit tests for tool re-exports Stacked on #1432 ## Test plan - [ ] `bun run test:unit` in `packages/ai-sdk` Made with [Cursor](https://cursor.com)
|
Note Production impact unlikely. Checked the packages/tools rewrite, CI workflows, and docs against the attached workers; supermemory-mcp (apps/mcp) and supermemory-app (apps/web) neither import nor depend on @supermemory/tools, so this PR ships no runtime code to production. Failure trajectories: none plausible. 1 failure mode was considered and refuted against observed production traffic. Refuted trajectory (1): what was ruled out, and why
Dependency changes
Polylane analysed |

Summary
tools-shared.tsTOOL_DESCRIPTIONS/PARAMETER_DESCRIPTIONSfrom package indexStacked on #1431
Test plan
bun run test:unitinpackages/toolsMade with Cursor